package fr.inserm.u674.chcdbweb.model.forms;

import java.util.Collection;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

/**
 * Utility class for forms. This class contains commonly used request parameter processing and
 * validation logic which are been refactored in single static methods.
 * 
 * @author BalusC
 * @link http://balusc.blogspot.com/2008/07/dao-tutorial-use-in-jspservlet.html
 */
public final class FormUtil {

	// Constructors -------------------------------------------------------------------------------

	private FormUtil() {
		// Utility class, hide constructor.
	}

	// Request parameter processing ---------------------------------------------------------------

	/**
	 * Returns the form field value from the given request associated with the given field name. It
	 * returns null if the form field value is null or is empty after trimming all whitespace.
	 * 
	 * @param request
	 *            The request to return the form field value for.
	 * @param fieldName
	 *            The field name to be associated with the field value.
	 * @return The form field value from the given request associated with the given field name.
	 */
	public static String getFieldValue(HttpServletRequest request, String fieldName) {
		String value = request.getParameter(fieldName);
		if (isEmpty(value))
			return null;
		else
			return value;
	}

	// Validation ---------------------------------------------------------------------------------

	/**
	 * Returns true if the given value is null or is empty.
	 * 
	 * @param value
	 *            The value to be checked on emptiness.
	 * @return True if the given value is null or is empty.
	 */
	public static boolean isEmpty(Object value) {
		if (value == null) {
			return true;
		}
		else if (value instanceof String) {
			return ((String) value).trim().length() == 0;
		}
		else if (value instanceof Object[]) {
			return ((Object[]) value).length == 0;
		}
		else if (value instanceof Collection<?>) {
			return ((Collection<?>) value).size() == 0;
		}
		else if (value instanceof Map<?, ?>) {
			return ((Map<?, ?>) value).size() == 0;
		}
		else {
			return value.toString() == null || value.toString().trim().length() == 0;
		}
	}

	/**
	 * Returns true if the given old value does not equals the given new value.
	 * 
	 * @param oldValue
	 *            The old value to be compared with the new value. The value may be null.
	 * @param newValue
	 *            The new value to be compared with the old value. The value may be null.
	 * @return True if the given old value does not equals the given new value.
	 */
	public static boolean isChanged(Object oldValue, Object newValue) {
		return oldValue == null ? newValue != null : !oldValue.equals(newValue);
	}

	/**
	 * Returns true if the given string is a valid email address.
	 * 
	 * @param string
	 *            The string to be checked on being a vaild email address.
	 * @return True if the given string is a valid email address.
	 */
	public static boolean isEmail(String string) {
		return string.matches("([^.@]+)(\\.[^.@]+)*@([^.@]+\\.)+([^.@]+)");
	}

	/**
	 * Returns true if the given string is a valid positive number.
	 * 
	 * @param string
	 *            The string to be checked on being a vaild positive number.
	 * @return True if the given string is a valid positive number.
	 */
	public static boolean isNumber(String string) {
		return string.matches("^\\d+$");
	}

	/**
	 * Returns true if the form checkbox field value is not null and equal to "on". Returns false
	 * otherwise
	 * 
	 * @param checkboxFieldName
	 *            The checkbox field name to be associated with the field value.
	 * @return true if the checkbox is checked, false otherwise.
	 */
	public static boolean isCheckboxChecked(String checkboxFieldName) {
		if (isEmpty(checkboxFieldName))
			return false;
		else
			return checkboxFieldName.equals("on");
	}

}